package sen.queryUtils;

import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.hibernate.Query;
import org.hibernate.Session;

/**
 * 用hibernate查询Bean的辅助类
 * 此类的查询没有处理异常和事务，所以只适合外部已经作了异常和事务处理的情况
 * 如，在sping的AOP中
 * @author sen
 */
public class HBQueryBean {

	private Session session;
	
	private Map<String, String> param;
	
	private String className;
	
	private boolean useNativeSqlQuery;
	
	private String sql;
	private String countSql;
	private String col;
	private String order;
	
	private String w = "";
	private String cw = "";
	
	private int rowStart;
	private int pageSize;
	
	private String sqlWherePre;
	private String countSqlWherePre;
	
	public HBQueryBean(Session session, Map<String, String> param,
			String className) {
		this(session, param, className, null, null);
	}
	
	public HBQueryBean(Session session, Map<String, String> param,
			String sql, String countSql) {
		this(session, param, null, sql, countSql);
	}
	
	public HBQueryBean(Session session, Map<String, String> param,
			String className, String sql, String countSql) {
		this.session = session;
		this.param = param;
		this.className = className;
		this.sql = sql;
		this.countSql = countSql;
	}

	private void setOtherValue() {
		if(null!=param && !param.isEmpty()) {
			try {
				rowStart = Integer.parseInt(param.get("rowStart"));
				pageSize = Integer.parseInt(param.get("pageSize"));
			} catch (Exception e) {
			}
			col = param.get("col");
			order = param.get("order");
		}
		
		setWhereContent();
		
		String orderStr = ((null!=col&&!"".equals(col) && null!=order&&!"".equals(order))?" order by " + col + " "+order:"");
		
		if(null != sql && !"".equals(sql)) {
			this.sql = sql + w +orderStr;
		} else {
			this.sql = "from "+ className +" as t " + w +orderStr;
		}
		
		if(null != countSql && !"".equals(countSql)) {
			this.countSql = countSql + cw;
		} else {
			this.countSql = "select count(*) from "+ className +" as t" + cw;
		}
	}
	
	public List query() throws Exception {
		setOtherValue();
		
		List list = null;
		boolean b = rowStart>=0 && pageSize>0;
		
		Query query = null;
		if(useNativeSqlQuery) {
			query = session.createSQLQuery(sql);
		} else {
			query = session.createQuery(sql);
		}

		if(b) {
			query.setFirstResult(rowStart);
			query.setMaxResults(pageSize);
		}
		list = query.list();

		if(b) {
			//查总记录数
			List l = null;
			if(useNativeSqlQuery) {
				l = session.createSQLQuery(countSql).list();
			} else {
				l = session.createQuery(countSql).list();
			}
			list.add(l.get(0));
		} else {
			list.add(list.size());
		}
		
		return list;
	}
	
	private void setWhereContent() {
		StringBuilder sb = new StringBuilder();
		for (Iterator<String> iterator = param.keySet().iterator(); iterator.hasNext();) {
			String key = iterator.next();
			if(key !=null && !"".equals(key) 
					&& !"col".equals(key)
					&& !"order".equals(key)
					&& !"rowStart".equals(key)
					&& !"pageSize".equals(key)) {
				if(param.get(key) !=null && !"".equals(param.get(key))) {
//					if("receiver.handlerId".equals(key)
//						|| "receiver.handlerId".equals(key)
//						|| "input.inputClerk.handlerId".equals(key)
//						|| "usedState".equals(key)
//						|| "sendState".equals(key)) {
//						sb.append(" t."+ key +" = '" + param.get(key) + "' and ");
//					} else {
//						sb.append(key +" like '%" + param.get(key) + "%' and ");
						sb.append(key +" = '" + param.get(key) + "' and ");
//					}
				}
			}
		}
		
		if(!"".equals(sb.toString())) {
			sb.delete(sb.lastIndexOf("and"), sb.length());
			StringBuilder t = new StringBuilder(sb.toString());
			
			if(!isNull(sqlWherePre)){
				t.insert(0, sqlWherePre + " and ");
			} else {
				t.insert(0, " where ");
			}
			
			w = t.toString();
			
			if(!isNull(countSqlWherePre)) {
				sb.insert(0, countSqlWherePre + " and ");
			} else {
				sb.insert(0, " where ");
			}
			cw = sb.toString();
		} else {
			if(!isNull(sqlWherePre)) {
				w = sqlWherePre;
			}
			if(!isNull(countSqlWherePre)) {
				cw = countSqlWherePre;
			}
		}
	}

	private static boolean isNull(String s) {
		return null == s || "".equals(s);
	}
	
	public Session getSession() {
		return session;
	}

	public void setSession(Session session) {
		this.session = session;
	}

	public Map<String, String> getParam() {
		return param;
	}

	public void setParam(Map<String, String> param) {
		this.param = param;
	}

	public String getClassName() {
		return className;
	}

	public void setClassName(String className) {
		this.className = className;
	}

	public String getSql() {
		return sql;
	}

	public void setSql(String sql) {
		this.sql = sql;
	}

	public String getCountSql() {
		return countSql;
	}

	public void setCountSql(String countSql) {
		this.countSql = countSql;
	}

	public boolean isUseNativeSqlQuery() {
		return useNativeSqlQuery;
	}

	public void setUseNativeSqlQuery(boolean useNativeSqlQuery) {
		this.useNativeSqlQuery = useNativeSqlQuery;
	}

	public String getSqlWherePre() {
		return sqlWherePre;
	}

	public void setSqlWherePre(String sqlWherePre) {
		this.sqlWherePre = sqlWherePre;
	}

	public String getCountSqlWherePre() {
		return countSqlWherePre;
	}

	public void setCountSqlWherePre(String countSqlWherePre) {
		this.countSqlWherePre = countSqlWherePre;
	}
}